//
// Created by 郝羽 on 2017/12/15.
//

#ifndef RTC_XSWITCH2_OVERUSE_DETECTOR_TEST_HPP
#define RTC_XSWITCH2_OVERUSE_DETECTOR_TEST_HPP

#include "test/catch.hpp"

#include <cstdint>
#include <cstdio>

#include "bwe/inter_arrival.hpp"
#include "bwe/overuse_detector.hpp"
#include "bwe/overuse_estimator.hpp"
#include "test/random.hpp"


namespace test {

class OveruseDetectorTest {
public:
    OveruseDetectorTest()
            : now_ms_(0),
              receive_time_ms_(0),
              rtp_timestamp_(10 * 90),
              overuse_detector_(),
              overuse_estimator_(999),
              inter_arrival_(5 * 90, 1.0 / 90.0),
              random_(123456789)    {};

    int Run100000Samples(int packets_per_frame, size_t packet_size, int mean_ms, int std_dev_ms) {
        int unique_overuse = 0;
        int last_overuse = -1;
        test::NormDist rd(0, std_dev_ms);
        for (int i = 0; i < 100000; ++i) {
            for (int j = 0; j < packets_per_frame; ++j) {
                UpdateDetector(rtp_timestamp_, receive_time_ms_, packet_size);
            }
            rtp_timestamp_ += mean_ms * 90;
            now_ms_ += mean_ms;
            receive_time_ms_ = std::max<int64_t>(receive_time_ms_, now_ms_ + static_cast<int64_t>(random_.Gaussian(0, std_dev_ms) + 0.5));
            if (overuse_detector_.Hypothesis() == bwe::Usage::OverUsing) {
                if (last_overuse + 1 != i) {
                    unique_overuse++;
                }
                last_overuse = i;
            }
        }
        return unique_overuse;
    };

    int RunUntilOveruse(int packets_per_frame, size_t packet_size, int mean_ms, int std_dev_ms, int drift_per_frame_ms) {
        test::NormDist rd(0, std_dev_ms);
        for (int i = 0; i < 1000; ++i) {
            for (int j = 0; j < packets_per_frame; ++j) {
                UpdateDetector(rtp_timestamp_, receive_time_ms_, packet_size);
            };

            rtp_timestamp_ += mean_ms * 90;
            now_ms_ += mean_ms + drift_per_frame_ms;
            receive_time_ms_ = std::max<int64_t>(receive_time_ms_, now_ms_ + static_cast<int64_t>(random_.Gaussian(0, std_dev_ms) + 0.5));

            if (overuse_detector_.Hypothesis() == bwe::Usage::OverUsing) {
                return i+1;
            }
        }
        return -1;
    };

    void UpdateDetector(uint32_t rtp_ts, int64_t r_t_ms, int32_t size) {
        uint32_t ts_delta;
        int64_t t_delta;
        int size_delta;
        if (inter_arrival_.ComputeDelta(ts_delta, t_delta, size_delta, rtp_ts, r_t_ms, size, r_t_ms)) {
            double ts_delta_ms = ts_delta / 90.0;
            auto deltas_offset = overuse_estimator_.Estimate(r_t_ms, overuse_detector_.Hypothesis(), ts_delta_ms, t_delta, size_delta);
            overuse_detector_.DetectUsage(r_t_ms, ts_delta_ms, deltas_offset.second, deltas_offset.first);
        }
    };

    int64_t now_ms_;
    int64_t receive_time_ms_;
    uint32_t rtp_timestamp_;
    bwe::OveruseDetector overuse_detector_;
    bwe::OveruseEstimator overuse_estimator_;
    bwe::InterArrival inter_arrival_;
    test::GoogleRandom random_;
};

};

TEST_CASE("Gaussian Random", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    int buckets[100] = {0,};

    for (int i = 0; i < 10000; ++i) {
        int index = detect.random_.Gaussian(49, 10);
        if (index >= 0 && index < 100) {
            buckets[index]++;
        }
    };

    for (int n = 0; n < 100; ++n) {
        std::cout << "Bucket " << n << ":" << buckets[n] << std::endl;
    }
};

TEST_CASE("No overuse 30 fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    uint32_t frame_duration_ms = 33;
    uint32_t rtp_timestamp = 10 * 90;

    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.now_ms_ += frame_duration_ms;
        rtp_timestamp += frame_duration_ms * 90;
        REQUIRE(detect.overuse_detector_.Hypothesis() != bwe::Usage::OverUsing);
    }
};

TEST_CASE("No overuse with receive variance", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    uint32_t frame_duration_ms = 10;
    uint32_t rtp_timestamp = 10 * 90;
    size_t packet_size = 1200;

    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        rtp_timestamp += frame_duration_ms * 90;
        if (i % 2) {
            detect.now_ms_ += frame_duration_ms - 5;
        } else {
            detect.now_ms_ += frame_duration_ms + 5;
        }
        REQUIRE(detect.overuse_detector_.Hypothesis() != bwe::Usage::OverUsing);
    }
};

TEST_CASE("No overuse with rtp timestamp variance", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    uint32_t frame_duration_ms = 10;
    uint32_t rtp_timestamp = 10 * 90;
    size_t packet_size = 1200;

    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.now_ms_ += frame_duration_ms;
        if (i % 2) {
            rtp_timestamp += (frame_duration_ms - 5) * 90;
        } else {
            rtp_timestamp += (frame_duration_ms + 5) * 90;
        }
        REQUIRE(detect.overuse_detector_.Hypothesis() != bwe::Usage::OverUsing);
    }
};


TEST_CASE("overuse 2000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 6;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 0;  // No variance.

    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                        frame_duration_ms, sigma_ms);

    REQUIRE(unique_overuse == 0);

    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                             frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 7);
};

TEST_CASE("overuse 100kbps 10fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 100;
    int drift_per_frame_ms = 1;
    int sigma_ms = 0;  // No variance.
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);

    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 7);
};

TEST_CASE("overuse with high variance 100kbps 10fps", "[overuse-detector][webrtc-disabled]") {
    test::OveruseDetectorTest detect;

    uint32_t frame_duration_ms = 100;
    uint32_t drift_per_frame_ms = 10;
    uint32_t rtp_timestamp = frame_duration_ms * 90;
    size_t packet_size = 1200;
    int offset = 10;

    // Run 1000 samples to reach steady state.
    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        rtp_timestamp += frame_duration_ms * 90;
        if (i % 2) {
            offset = detect.random_.Rand(0, 49);
            detect.now_ms_ += frame_duration_ms - offset;
        } else {
            detect.now_ms_ += frame_duration_ms + offset;
        }
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    // Simulate a higher send pace, that is too high.
    // Above noise generate a standard deviation of approximately 28 ms.
    // Total build up of 150 ms.
    for (int j = 0; j < 15; ++j) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.now_ms_ += frame_duration_ms + drift_per_frame_ms;
        rtp_timestamp += frame_duration_ms * 90;
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
    REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::OverUsing);
};

TEST_CASE("overuse with low variance 100kbps 10fps", "[overuse-detector][webrtc-disabled]") {
    test::OveruseDetectorTest detect;

    uint32_t frame_duration_ms = 100;
    uint32_t drift_per_frame_ms = 1;
    uint32_t rtp_timestamp = frame_duration_ms * 90;
    size_t packet_size = 1200;
    int offset = 10;

    // Run 1000 samples to reach steady state.
    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        rtp_timestamp += frame_duration_ms * 90;
        if (i % 2) {
            offset = detect.random_.Rand(0, 1);
            detect.now_ms_ += frame_duration_ms - offset;
        } else {
            detect.now_ms_ += frame_duration_ms + offset;
        }
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    // Simulate a higher send pace, that is too high.
    // Total build up of 6 ms.
    for (int j = 0; j < 6; ++j) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.now_ms_ += frame_duration_ms + drift_per_frame_ms;
        rtp_timestamp += frame_duration_ms * 90;
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
    REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::OverUsing);
};

TEST_CASE("over use with low variance 2000kbps 30 fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;
    test::UniformDist rd(0, 1);

    uint32_t frame_duration_ms = 33;
    uint32_t drift_per_frame_ms = 1;
    uint32_t rtp_timestamp = frame_duration_ms * 90;
    size_t packet_size = 1200;
    int offset = 0;

    // Run 1000 samples to reach steady state.
    for (int i = 0; i < 1000; ++i) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        rtp_timestamp += frame_duration_ms * 90;
        if (i % 2) {
            offset = rd.Random();
            detect.now_ms_ += frame_duration_ms - offset;
        } else {
            detect.now_ms_ += frame_duration_ms + offset;
        }
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    
    // Simulate a higher send pace, that is too high.
    // Total build up of 30 ms.
    for (int j = 0; j < 3; ++j) {
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
        detect.now_ms_ += frame_duration_ms + drift_per_frame_ms * 6;
        rtp_timestamp += frame_duration_ms * 90;
        REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::Normal);
    }
    detect.UpdateDetector(rtp_timestamp, detect.now_ms_, packet_size);
    REQUIRE(detect.overuse_detector_.Hypothesis() == bwe::Usage::OverUsing);

};


TEST_CASE("low Gaussian variance 30kbps 3fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 333;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                        frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                             frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 20);
};


TEST_CASE("low Gaussian variance fast drift 30kbps 3fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 333;
    int drift_per_frame_ms = 100;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                        frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                             frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 4);
};

TEST_CASE("high Gaussian variance 30kbps 3fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 333;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                        frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                             frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("high Gaussian variance fast drift 30kbps 3fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 333;
    int drift_per_frame_ms = 100;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                        frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                             frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 4);
};

TEST_CASE("low Gaussian variance 100kbps 5fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 2;
    int frame_duration_ms = 200;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 20);
};

TEST_CASE("high Gaussian variance 100kbps 5fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;
    size_t packet_size = 1200;

    int packets_per_frame = 2;
    int frame_duration_ms = 200;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("low Gaussian variance 100kbps 10fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 100;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 20);
};

TEST_CASE("high Gaussian variance 100kbps 10fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 100;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("low Gaussian variance 300kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 19);
};

TEST_CASE("low Gaussian variance fast drift 300kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 5);
};

TEST_CASE("high Gaussian variance 300kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("high Gaussian variance fast drift 300kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 1;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 10);
};

TEST_CASE("low Gaussian variance 1000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 3;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 19);
};

TEST_CASE("low Gaussian variance fast drift 1000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 3;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 5);
};

TEST_CASE("high Gaussian variance 1000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 3;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("high Gaussian variance fast drift 1000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 3;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 10);
};

TEST_CASE("low Gaussian variance 2000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 6;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 19);
};

TEST_CASE("low Gaussian variance fast drift 2000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 6;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 3;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 5);
};

TEST_CASE("high Gaussian variance 2000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 6;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 1;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 44);
};

TEST_CASE("high Gaussian variance fast drift 2000kbps 30fps", "[overuse-detector]") {
    test::OveruseDetectorTest detect;

    size_t packet_size = 1200;
    int packets_per_frame = 6;
    int frame_duration_ms = 33;
    int drift_per_frame_ms = 10;
    int sigma_ms = 10;
    int unique_overuse = detect.Run100000Samples(packets_per_frame, packet_size,
                                                 frame_duration_ms, sigma_ms);
    REQUIRE(unique_overuse == 0);
    int frames_until_overuse = detect.RunUntilOveruse(packets_per_frame, packet_size,
                                                      frame_duration_ms, sigma_ms, drift_per_frame_ms);
    REQUIRE(frames_until_overuse == 10);
};


#endif //RTC_XSWITCH2_OVERUSE_DETECTOR_TEST_HPP
